﻿package com.library.utils.vily
{
	//org.vily.utils.DrawArc;
	
	import flash.display.Sprite;

	public class DrawArc{
		/*本类用于绘制圆弧*/		
	
		//当前目标剪辑所在的坐标的矢量
		private var currentVector:Vector_2D = null;
		//记录由圆心点指向当前目标剪辑所在的坐标的矢量
		private var minusVec:Vector_2D = null;
		//
		private var nextPVector:Vector_2D = null;
		//弧度
		private var currRad:Number = 0;
		
		public function DrawArc(){
			init();
		}
		private function init():void{
			currentVector = new Vector_2D(0,0);
			nextPVector = new Vector_2D(0,0);		
		}
		/**
			speed<0逆时针运动,否则为顺时针运动,但是此转动不是物体自身的转动，而是它绕某一点的转动
			根据当前的点以及圆心，半径，计算出下一点
		*/
		private function getNextPos(pos:Vector_2D,speed:Number,centerVector:Vector_2D,p_r_num:Number = 1):Vector_2D{
			//获取currMc当前所在容器的全局坐标,计算出自己相对于圆心坐标的方向的弧度值
			//trace(centerVector);
			currentVector.setTo(pos.x,pos.y);
			
			minusVec = currentVector.minusNew(centerVector);
			currRad = minusVec.getRadian();
			var tempRad:Number = currRad - Math.PI/2;
			
			var p_x:Number = pos.x - speed*Math.cos(tempRad);
			var p_y:Number = pos.y - speed*Math.sin(tempRad);
			
			nextPVector.setTo(p_x,p_y);
			minusVec = nextPVector.minusNew(centerVector);
			//规范化，将currMc拉回到圆弧轨迹之上
			minusVec.normalize();
			p_x = centerVector.x + minusVec.x * p_r_num;
			p_y = centerVector.y + minusVec.y * p_r_num;
			pos.x = p_x;
			pos.y = p_y;
			return pos.clone();
		}
		//由起点,圆心坐标,半径,夹角为0(水平向右)来绘制单个圆弧
		public function drawAngleArc(spr:Sprite,c_pos:Vector_2D,start_angle:Number,r_num:Number = 1,d_angle:Number = 30,minDis:Number = 1,isClear:Boolean = true):void{
			var pos_arr:Array = [];
			
			if(d_angle <= 0){
				trace("DrawArc::drawAngleArc(), Erroror:  d_angle不可以小于等于0  ");
				return;
			}else if(minDis == 0){
				return;
			}
			if(d_angle % 360 == 0){
			}else{
				d_angle = d_angle%360;
			}			
			//总弧长
			var arcLen:Number = (d_angle / 180) * r_num * Math.PI;
			//trace("arcLen: "+arcLen);
			//起始的角度			
			start_angle = (start_angle+360) % 360;
			var rad:Number = (start_angle / 180) * Math.PI;
			var start_pos:Vector_2D = new Vector_2D(0,0);
			start_pos.x = r_num * Math.cos( rad ) + c_pos.x;
			start_pos.y = r_num * Math.sin( rad ) + c_pos.y;
			
			//首先计算出终止位置的pos
			
			if(minDis>0){
				rad = (((start_angle+d_angle)%360) / 180) * Math.PI;
			}else{
				rad = (((start_angle - d_angle)%360) / 180) * Math.PI;
			}
			var endPos:Vector_2D = new Vector_2D(0,0);
			endPos.x = r_num * Math.cos( rad ) + c_pos.x;
			endPos.y = r_num * Math.sin( rad ) + c_pos.y;
			
			//当前的角度
			var curr_angle:Number = 0;
			//记录弧长
			var tem_arcLen:Number = 0;
			var next_pos:Vector_2D = start_pos.clone();
			pos_arr.push(start_pos);
			d_angle = 0;
			var num:int = 1000;
			var type:int = -2;
			var tempD:Number = 0;
			var t_d_angle:Number = 0;
			for(var i:int = 0;i<num; i++){
				
				next_pos = getNextPos(next_pos,minDis,c_pos,r_num);
				
				//计算由此点到起点的弧长
				curr_angle = (next_pos.minusNew(c_pos)).getAngle() + tempD;
				
				if(curr_angle > start_angle){
					if(type==-2){
						type = 1;
					}else if(type == -1){
						//顺时针旋转时由几十度转到300多度(<360)这种到达一个周期的转换
						if(tempD==0){							
							tempD = -360;
							curr_angle += tempD;
						}
						type = 1;
					}
					
				}else if(curr_angle < start_angle){
					if(type==-2){
						type = -1;
					}else if(type == 1){
						//顺时针旋转时由300多度(<360)转到几十度这种到达一个周期的转换
						if(tempD==0){
							tempD = 360;
							curr_angle += tempD;
						}
						type = -1;
					}
				}
				t_d_angle = curr_angle - start_angle;
				d_angle += t_d_angle;
				start_angle = curr_angle;
				//t_d_angle是为了预检测
				tem_arcLen = ((d_angle + t_d_angle) / 180) * r_num * Math.PI;
				//trace(tem_arcLen);
				if(Math.abs(tem_arcLen) >= arcLen){					
					pos_arr.push(endPos);
					break;
				}else{					
					pos_arr.push(next_pos);
				}
			}
			
			//绘制弧线
			num = pos_arr.length;
			if(num>1){				
				if(isClear){
					spr.graphics.clear();
				}
				spr.graphics.lineStyle(1,0x000000);
				spr.graphics.moveTo(pos_arr[0].x,pos_arr[0].y);
				for(i = 1;i<num; i++){
					spr.graphics.lineTo(pos_arr[i].x,pos_arr[i].y);
				}				
			}
			start_pos = null;
			endPos = null;
			next_pos = null;
		}
		
		//由起点,圆心坐标,半径,夹角为0(水平向右)来绘制圆弧,此方法获取构成这个圆弧的点的数据
		public function getAngleArcPosArr(c_pos:Vector_2D,start_angle:Number,r_num:Number = 1,d_angle:Number = 30,minDis:Number = 1):Array{
			var pos_arr:Array = [];
			
			if(d_angle <= 0){
				trace("DrawArc::drawAngleArc(), Erroror:  d_angle不可以小于等于0  ");
				return null;
			}else if(minDis == 0){
				return null;
			}
			if(d_angle % 360 == 0){
			}else{
				d_angle = d_angle%360;
			}
			var pre_d_angle:Number = d_angle;
			//总弧长
			var arcLen:Number = (d_angle / 180) * r_num * Math.PI;
			//trace("arcLen: "+arcLen);
			//起始的角度			
			start_angle = (start_angle+360) % 360;
			var rad:Number = (start_angle / 180) * Math.PI;
			var start_pos:Vector_2D = new Vector_2D(0,0);
			start_pos.x = r_num * Math.cos( rad ) + c_pos.x;
			start_pos.y = r_num * Math.sin( rad ) + c_pos.y;
			
			//首先计算出终止位置的pos
			
			if(minDis>0){
				rad = (((start_angle + d_angle)%360) / 180) * Math.PI;
			}else{
				rad = (((start_angle - d_angle)%360) / 180) * Math.PI;
			}
			var endPos:Vector_2D = new Vector_2D(0,0);
			endPos.x = r_num * Math.cos( rad ) + c_pos.x;
			endPos.y = r_num * Math.sin( rad ) + c_pos.y;
			
			//当前的角度
			var curr_angle:Number = 0;
						
			//记录弧长
			var tem_arcLen:Number = 0;
			
			
			var next_pos:Vector_2D = start_pos.clone();
			pos_arr.push(start_pos);
			d_angle = 0;
			var num:int = 1000;
			var type:int = -2;
			var tempD:Number = 0;
			var t_d_angle:Number = 0;
			for(var i:int = 0;i<num; i++){
				
				next_pos = getNextPos(next_pos,minDis,c_pos,r_num);
				
				//计算由此点到起点的弧长
				curr_angle = (next_pos.minusNew(c_pos)).getAngle() + tempD;
				
				if(curr_angle > start_angle){
					if(type==-2){
						type = 1;
					}else if(type == -1){
						//顺时针旋转时由几十度转到300多度(<360)这种到达一个周期的转换
						if(tempD==0){							
							tempD = -360;
							curr_angle += tempD;
						}
						type = 1;
					}
					
				}else if(curr_angle < start_angle){
					if(type==-2){
						type = -1;
					}else if(type == 1){
						//顺时针旋转时由300多度(<360)转到几十度这种到达一个周期的转换
						if(tempD==0){
							tempD = 360;
							curr_angle += tempD;
						}
						type = -1;
					}
				}
				t_d_angle = curr_angle - start_angle;
				d_angle += t_d_angle;
				start_angle = curr_angle;
				//t_d_angle是为了预检测
				tem_arcLen = ((d_angle + t_d_angle) / 180) * r_num * Math.PI;
				//trace(tem_arcLen);
				if(Math.abs(tem_arcLen) >= arcLen){					
					pos_arr.push(endPos);
					break;
				}else{					
					pos_arr.push(next_pos);
				}
			}
			
			start_pos = null;
			endPos = null;
			next_pos = null;
			if(num>1){
				return pos_arr;
			}else{
				return null;
			}
		}
	}

}